package com.traffic.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.traffic.constant.Status;
import com.traffic.entity.Bigdata;
import com.traffic.entity.Guest;
import com.traffic.entity.Rank;
import com.traffic.entity.UserInfo;
import com.traffic.model.*;
import com.traffic.service.*;
import com.traffic.util.BaidumapUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(tags = "消息推送相关接口")
@RestController
@RequestMapping(value = "/statistic")
@Slf4j
public class StatisticController {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    RankService rankService;

    @Autowired
    GuestService guestService;

    @Autowired
    BigdataService bigdataService;

    @Autowired
    BaidumapService baidumapService;

    @Autowired
    BaidumapUtil baidumapUtil;

    @ApiOperation(value = "【数据统计】总下载用户数", notes = "下载用户数量")
    @GetMapping("/getusernumber")
    public ApiResponse GetUserNumber() {
        Integer count = userInfoService.count();

        return ApiResponse.ofStatus(Status.OK,count);
    }


    @ApiOperation(value = "【数据统计】活跃用户数", notes = "分性别活跃用户")
    @GetMapping("/getactiveuser")
    public ApiResponse GetActiveUser() {
        QueryWrapper<UserInfo> wrapperM = new QueryWrapper<>();
        QueryWrapper<UserInfo> wrapperF = new QueryWrapper<>();
        Integer countm = userInfoService.count(wrapperM.last("WHERE sex = 0 AND DateDiff(NOW(),last_update_time)<=7"));
        Integer countf = userInfoService.count(wrapperF.last("WHERE sex = 1 AND DateDiff(NOW(),last_update_time)<=7"));

        return ApiResponse.ofStatus(Status.OK,countm.toString()+","+countf);
    }


    @ApiOperation(value = "【数据统计】活跃用户数", notes = "分性别活跃用户")
    @GetMapping("/getuserage")
    public ApiResponse GetUserAge() {
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        List<Object> ages= userInfoService.listObjs(wrapper.select("ROUND(DATEDIFF(CURDATE(), birthday)/365.2422)"));

        List<Integer> Iage = new ArrayList<>();

        for (Object o:ages) {
            Iage.add(Integer.parseInt(o.toString()));
        }
        Integer sum = 0;
        Integer count = Iage.size();
        Integer min=0;
        Integer max=0;
        for (Integer age:Iage) {
            sum = sum+age;
            if(max<age)max = age;
            if(min>age)min = age;
        }

        Double average = Double.parseDouble(sum.toString())/Double.parseDouble(count.toString());
        DecimalFormat df = new DecimalFormat("######0.00");
        df.format(average);

        return ApiResponse.ofStatus(Status.OK,max.toString()+","+min.toString()+","+average);
    }


    @ApiOperation(value = "【数据统计】系统总记录", notes = "系统各项总记录")
    @GetMapping("/getsysdata")

    public ApiResponse GetSystemData() {

        QueryWrapper<Rank> wrapperM = new QueryWrapper<>();
        QueryWrapper<Rank> wrapperV1 = new QueryWrapper<>();
        QueryWrapper<Rank> wrapperV2 = new QueryWrapper<>();

        QueryWrapper<Rank> wrapperA1 = new QueryWrapper<>();
        QueryWrapper<Rank> wrapperA2 = new QueryWrapper<>();

        QueryWrapper<Rank> wrapperNA1 = new QueryWrapper<>();
        QueryWrapper<Rank> wrapperNA2 = new QueryWrapper<>();


        Integer usercount = rankService.count();
        String temp = rankService.listObjs(wrapperM.select("SUM(his_mileage)")).toString();
        Double summileage = Double.parseDouble(StringUtils.strip(temp,"[]"));
        Double averagemileage = summileage/usercount;

        temp = rankService.listObjs(wrapperV1.select("MAX(max_vel)")).toString();
        Double maxspeed = Double.parseDouble(StringUtils.strip(temp,"[]"));
        temp = rankService.listObjs(wrapperV2.select("SUM(his_vel)")).toString();
        Double averagespeed = Double.parseDouble(StringUtils.strip(temp,"[]"))/usercount;

        temp = rankService.listObjs(wrapperA1.select("MAX(max_acc)")).toString();
        Double maxacc = Double.parseDouble(StringUtils.strip(temp,"[]"));

        temp = rankService.listObjs(wrapperA2.select("SUM(his_acc)")).toString();
        Double averageacc = Double.parseDouble(StringUtils.strip(temp,"[]"))/usercount;

        temp = rankService.listObjs(wrapperNA1.select("MAX(max_n_acc)")).toString();
        Double nmaxacc = Double.parseDouble(StringUtils.strip(temp,"[]"));

        temp = rankService.listObjs(wrapperNA2.select("SUM(max_n_acc)")).toString();
        Double naverageacc = Double.parseDouble(StringUtils.strip(temp,"[]"))/usercount;

        SysdataResult sysdataResult = new SysdataResult();

        sysdataResult.setAverageacc(averageacc);
        sysdataResult.setAveragemileage(averagemileage);
        sysdataResult.setAveragespeed(averagespeed);
        sysdataResult.setMaxacc(maxacc);
        sysdataResult.setMaxspeed(maxspeed);
        sysdataResult.setNaverageacc(maxacc);
        sysdataResult.setNmaxacc(nmaxacc);
        sysdataResult.setSummileage(summileage);


        return ApiResponse.ofStatus(Status.OK,sysdataResult);
    }

    @ApiOperation(value = "【数据统计】日访问数据", notes = "日访问用户数")
    @GetMapping("/getdayguest")
    public ApiResponse GetDayGuest() {

        List<Guest> guests = guestService.list();

        return ApiResponse.ofStatus(Status.OK,guests);
    }

    @ApiOperation(value = "【数据统计】月访问数据", notes = "月访问用户数")
    @GetMapping("/getmonthguest")
    public ApiResponse GetMonthGuest() {

        QueryWrapper<Guest> wrapper = new QueryWrapper<>();
        List<Object> month = guestService.listObjs(wrapper.select("DATE_FORMAT(create_time, '%Y-%m')").last("GROUP BY DATE_FORMAT(create_time, '%Y-%m')"));

        QueryWrapper<Guest> nwrapper = new QueryWrapper<>();
        List<Object> number = guestService.listObjs(nwrapper.select("SUM(number)").last("GROUP BY DATE_FORMAT(create_time, '%Y-%m')"));

        List<MGuestResult> mGuestResults = new ArrayList<>();

        for (int i = 0;i<month.size();i++){

            MGuestResult temp = new MGuestResult();
            temp.setMonth(month.get(i).toString());
            temp.setNumber(Long.parseLong(number.get(i).toString()));
            mGuestResults.add(temp);
        }

        return ApiResponse.ofStatus(Status.OK,mGuestResults);
    }

    @ApiOperation(value = "【数据统计】年访问数据", notes = "年访问用户数")
    @GetMapping("/getyearguest")
    public ApiResponse GetYearGuest() {

        QueryWrapper<Guest> wrapper = new QueryWrapper<>();
        List<Object> year = guestService.listObjs(wrapper.select("DATE_FORMAT(create_time, '%Y')").last("GROUP BY DATE_FORMAT(create_time, '%Y')"));

        QueryWrapper<Guest> nwrapper = new QueryWrapper<>();
        List<Object> number = guestService.listObjs(nwrapper.select("SUM(number)").last("GROUP BY DATE_FORMAT(create_time, '%Y')"));

        List<YGuestResult> yGuestResults = new ArrayList<>();

        for (int i = 0;i<year.size();i++){

            YGuestResult temp = new YGuestResult();
            temp.setYear(year.get(i).toString());
            temp.setNumber(Long.parseLong(number.get(i).toString()));
            yGuestResults.add(temp);
        }

        return ApiResponse.ofStatus(Status.OK,yGuestResults);
    }

    @ApiOperation(value = "【数据统计】城市分布", notes = "用户数按照注册城市分，由大到小进行排列")
    @GetMapping("/getcitydata")
    public ApiResponse GetCityData() {

        QueryWrapper<UserInfo> cwrapper = new QueryWrapper<>();
        List<Object> citys = userInfoService.listObjs(cwrapper.select("city").last("WHERE city is not null GROUP BY city"));

        QueryWrapper<UserInfo> nwrapper = new QueryWrapper<>();
        List<Object> counts = userInfoService.listObjs(nwrapper.select("COUNT(*)").last("WHERE city is not null GROUP BY city"));

        List<CityResult> cityResults = new ArrayList<>();

        for (int i = 0;i<citys.size();i++){
            CityResult temp = new CityResult();
            temp.setCity(citys.get(i).toString());
            temp.setCount(Long.parseLong(counts.get(i).toString()));
            cityResults.add(temp);
        }
        return ApiResponse.ofStatus(Status.OK, cityResults);
    }

    @ApiOperation(value = "【数据统计】热力图坐标", notes = "热力图坐标")
    @GetMapping("/gethotdata")
    public ApiResponse GetHotData() {
        String ak = baidumapUtil.getAk();
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("ak", ak);

        QueryWrapper<UserInfo> cwrapper = new QueryWrapper<>();
        List<Object> citys = userInfoService.listObjs(cwrapper.select("city").last("WHERE city is not null GROUP BY city"));

        QueryWrapper<UserInfo> nwrapper = new QueryWrapper<>();
        List<Object> counts = userInfoService.listObjs(nwrapper.select("COUNT(*)").last("WHERE city is not null GROUP BY city"));

        List<HotResult> hotResults = new ArrayList<>();

        for (int i = 0;i<citys.size();i++){

            HotResult temp = new HotResult();

            params.put("address",citys.get(i).toString());

            String loaction = baidumapService.CityGetLocation(params);

            temp.setCount(Long.parseLong(counts.get(i).toString()));
            temp.setLng(loaction.split(",")[0]);
            temp.setLat(loaction.split(",")[1]);

            hotResults.add(temp);

        }

        return ApiResponse.ofStatus(Status.OK, hotResults);
    }


    @ApiOperation(value = "【数据统计】按省份数据", notes = "省份数据")
    @GetMapping("/getprovincedata")
    public ApiResponse GetProvinceData() {




        List<HotResult> hotResults = new ArrayList<>();


        return ApiResponse.ofStatus(Status.OK, hotResults);
    }



    @ApiOperation(value = "【数据统计】用户数据分析", notes = "用户数据")
    @GetMapping("/getuserdata/{page}")
    public ApiResponse GetUserData(@PathVariable Integer page) {

        Integer count = userInfoService.count();
        IPage<UserInfo> userIPage = new Page<UserInfo>(page, 10,count);
        IPage<UserInfo> userbacks = userInfoService.page(userIPage);

        List<UserInfo> userInfos = userbacks.getRecords();

        List<Rank> ranks = new ArrayList<>();
        List<UserDataResult> userDataResults = new ArrayList<>();

        for (UserInfo u:userInfos) {

            ranks.add(rankService.getOne(new QueryWrapper<Rank>().eq("user_id",u.getUserId())));

        }


        for (int i=0;i<10;i++){
            UserDataResult userDataResult = new UserDataResult();

            userDataResult.setNickname(userInfos.get(i).getNickName());
            userDataResult.setCreatetime(userInfos.get(i).getCreateTime());
            userDataResult.setLevel(userInfos.get(i).getRank());
            userDataResult.setScore(ranks.get(i).getScore());
            userDataResult.setSex(userInfos.get(i).getSex()==1?"女":"男");
            userDataResult.setMaxspeed(ranks.get(i).getMaxVel());
            userDataResult.setMorningall(ranks.get(i).getMorningTime()/ranks.get(i).getAllTime());
            userDataResult.setAfternoonall(ranks.get(i).getAfternoonTime()/ranks.get(i).getAllTime());
            userDataResult.setEveningall(ranks.get(i).getEveningTime()/ranks.get(i).getAllTime());
            userDataResult.setAvespeed(ranks.get(i).getHisVel());
            userDataResult.setAveacc(ranks.get(i).getHisAcc());
            userDataResult.setMileage(ranks.get(i).getHisMileage());
            userDataResult.setStationary(ranks.get(i).getStationarity());

            Long userid = userInfos.get(i).getUserId();

            QueryWrapper<Bigdata> anglewrapper = new QueryWrapper<>();
            Object angle = bigdataService.listObjs(anglewrapper.select("AVG(x6)").last("WHERE user_id="+userid.toString()+" and type=2"));
            Double fangle = 0.0;
            if(ObjectUtils.isEmpty(angle)){
                fangle=0.0;
            }
            else{
                fangle = Double.parseDouble(StringUtils.strip(angle.toString(),"[]"));
            }
            userDataResult.setAveangle(fangle);

            QueryWrapper<Bigdata> attwrapper = new QueryWrapper<>();
            Object atten = bigdataService.listObjs(attwrapper.select("MAX(x3)").last("WHERE user_id="+userid.toString()+" and type=1"));
            Integer att = 0;
            if(ObjectUtils.isEmpty(atten)){
                att=0;
            }
            else{
                att = Integer.parseInt(StringUtils.strip(atten.toString(),"[]"));
            }
            String attenion="";
            if (att==0)attenion="专注开车";
            if (att==1)attenion="接打电话";
            if (att==2)attenion="玩手机";
            userDataResult.setAttention(attenion);

            userDataResult.setTurn_0(bigdataService.TurnPercent("x5","0",userid));
            userDataResult.setTurn_1(bigdataService.TurnPercent("x5","1",userid));
            userDataResult.setTurn_2(bigdataService.TurnPercent("x5","2",userid));
            userDataResult.setTurn_3(bigdataService.TurnPercent("x5","3",userid));
            userDataResult.setTurn_4(bigdataService.TurnPercent("x5","4",userid));
            userDataResult.setTurn_5(bigdataService.TurnPercent("x5","5",userid));

            userDataResult.setAcc_0(bigdataService.TurnPercent("x6","0",userid));
            userDataResult.setAcc_1(bigdataService.TurnPercent("x6","1",userid));
            userDataResult.setAcc_2(bigdataService.TurnPercent("x6","2",userid));
            userDataResult.setAcc_3(bigdataService.TurnPercent("x6","3",userid));
            userDataResult.setAcc_4(bigdataService.TurnPercent("x6","4",userid));
            userDataResult.setAcc_5(bigdataService.TurnPercent("x6","5",userid));

            userDataResult.setNacc_0(bigdataService.TurnPercent("x7","0",userid));
            userDataResult.setNacc_1(bigdataService.TurnPercent("x7","1",userid));
            userDataResult.setNacc_2(bigdataService.TurnPercent("x7","2",userid));
            userDataResult.setNacc_3(bigdataService.TurnPercent("x7","3",userid));
            userDataResult.setNacc_4(bigdataService.TurnPercent("x7","4",userid));
            userDataResult.setNacc_5(bigdataService.TurnPercent("x7","5",userid));

            userDataResult.setRoad_1(bigdataService.TurnPercent("x8","0",userid));
            userDataResult.setRoad_2(bigdataService.TurnPercent("x8","1",userid));
            userDataResult.setRoad_3(bigdataService.TurnPercent("x8","2",userid));

            userDataResults.add(userDataResult);

        }




        return ApiResponse.ofStatus(Status.OK,userDataResults);
    }



}
